/*
 * $Id: string.h,v 1.78 2005-12-26 16:46:40 bacon Exp $
 */

#ifndef _XP_BAS_STRING_H_
#define _XP_BAS_STRING_H_

#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/stdarg.h>

#define XP_STRFNMAT_PATHNAME (1 << 0)
#define XP_STRFNMAT_NOESCAPE (1 << 1)
#define XP_STRFNMAT_PERIOD   (1 << 2)
#define XP_STRFNMAT_CASEFOLD (1 << 3)

/*
 * TYPE: xp_vstr_t
 *   Defines a vectorized string 
 */
typedef struct xp_vstr_t xp_vstr_t;

struct xp_vstr_t
{
	xp_char_t   buffer_space[256];
	xp_char_t*  buffer;
	xp_size_t   buffer_capacity;
	xp_size_t   buffer_ubound;

	xp_char_t*  vector_space[64 + 1];
	xp_char_t** vector;
	xp_size_t   vector_capacity;
	xp_size_t   vector_ubound;

	xp_bool_t __dynamic;
};


#ifdef __cplusplus
extern "C" {
#endif

/*--------------------
     string_size.c 
  --------------------*/

/* GROUP: Size */

/*
 * FUNCTION: xp_strlen
 *   Calculates the number of characters in a string
 *
 * PARAMETERS:
 *   str - [in] a null-terminated string to examine
 *
 * RETURNS:
 *   The number of characters before the terminating '\0'.
 * 
 * SEE ALSO:
 *   <xp_strsize>
 */
xp_size_t xp_strlen (const xp_char_t* str);

/*
 * FUNCTION: xp_strlenn
 *   Calculates the number of characters in a string 
 * 
 * PARAMETERS:
 *   str - [in] a string to examine
 *   max - [in] the maximum length to return if xp_strlen(*str*) > *max*
 * 
 * RETURNS:
 *   The number of characters in *str* if xp_strlen(*str*) <= *max*.
 *   Otherwise *max* is returned.
 * 
 * SEE ALSO:
 *   <xp_strlen> <xp_strsizen>
 */
xp_size_t xp_strlenn (const xp_char_t* str, xp_size_t max);

/*
 * FUNCTION: xp_strsize
 *   Calculates the number of characters a string holds
 *
 * PARAMETERS:
 *   str - [in] a null-terminated string to examine
 *
 * RETURNS:
 *   The number of characters including the terminating '\0'.
 *   xp_strsize(*str*) is equal to xp_strlen(*str*) + 1.
 *
 * SEE ALSO:
 *   <xp_strlen> <xp_strsizen>
 */
xp_size_t xp_strsize (const xp_char_t* str); 

/*
 * FUNCTION: xp_strsizen
 *   Calculates the number of characters a string holds
 * 
 * PARAMETERS:
 *   str - [in] a string to examine
 *   max - [in] the maximum length to return if xp_strlen(*str*) > *max*
 * 
 * RETURNS:
 *   The number of characters including the terminating '\0' if it is found 
 *   before the *max*-th character. Otherwise *max* is returned.
 * 
 * SEE ALSO:
 *   <xp_strlen> <xp_strsize>
 */
xp_size_t xp_strsizen (const xp_char_t* str, xp_size_t max);


/*--------------------
     string_copy.c 
  --------------------*/

/* GROUP: Fill */

/*
 * FUNCTION: xp_strset
 *   Fills a string with a character
 * 
 * PARAMETERS:
 *   buf - [in out] a string buffer
 *   c - [in] a character to fill with
 *   n - [in] number of characters to fill
 *
 * RETURNS:
 *   Length of the filled string
 * 
 * DESCRIPTION:
 *   <xp_strset> fills the first *n* characters of *buf* with *c* and 
 *   inserts '\0' after them. It returns the number of characters excluding
 *   the terminating '\0'.
 *
 * SEE ALSO:
 *   <xp_strxset>
 */
xp_size_t xp_strset (xp_char_t* buf, xp_char_t c, xp_size_t n);

/*
 * FUNCTION: xp_strxset
 *   Fills a string with a character
 *
 * PARAMETERS:
 *   buf - [in out] a string buffer
 *   bsz - [in] size of *buf*
 *   c - [in] a character to fill with
 *   n - [in] number of characters to fill
 *
 * RETURNS:
 *   Length of the filled string
 *
 * DESCRIPTION:
 *   <xp_strxset> fills the first *n* characters of *buf* with *c* if *bsz* is 
 *   greater than *n*. Otherwise, it fills the first (*bsz* - 1) characters of 
 *   *buf* with *c*. In addition, it guarantees to null-terminate the buffer.
 *   It returns the number of characters excluding the terminating '\0'.
 *
 * SEE ALSO:
 *   <xp_strset>
 */
xp_size_t xp_strxset (xp_char_t* buf, xp_size_t bsz, xp_char_t c, xp_size_t n);

/* GROUP: Copy */

/*
 * FUNCTION: xp_strcpy
 *   Copies a string into a buffer
 * 
 * PARAMETERS:
 *   buf - [out] the buffer into which a string is copied 
 *   str - [in] a null-terminated string to copy
 *
 * RETURNS:
 *   The number of characters copied excluding the terminating '\0'. 
 *   The return value is equal to xp_strlen(*str*).
 * 
 * DESCRIPTION:
 *   <xp_strcpy> stops after the terminating '\0' of *str* is copied.
 *   The buffer must be large enough, at least xp_strlen(*str*) + 1, 
 *   to hold the source string including its terminating '\0'. Otherwise,
 *   it writes beyond the buffer space given, which results in a programming 
 *   bug. In most cases, it is safe to use <xp_strxcpy> despite a bit of 
 *   inefficiency.
 * 
 * SEE ALSO:
 *   <xp_strcpyn> <xp_strncpy> <xp_strxcpy> <xp_strxncpy>
 */
xp_size_t xp_strcpy (xp_char_t* buf, const xp_char_t* str);

/*
 * FUNCTION: xp_strcpyn
 *   Copies a length-bounded string to a buffer
 * 
 * PARAMETERS:
 *   buf - [out] the buffer into which a string is copied 
 *   str - [in] a string to copy
 *   n - [in] the maximum number of characters to copy if xp_strlen(*str*) > *n*
 * 
 * RETURNS:
 *   The number of characters copied excluding the terminating '\0'.
 * 
 * DESCRIPTION:
 *   <xp_strcpyn> stops after at most *n* characters or the terminating '\0' 
 *   of *str* has been copied. In the former case, '\0' is not appened to 
 *   *buf* unless the *n*-th character of *str* is '\0'. Take note that *buf*
 *   must be large enough to hold *str*.
 *
 * SEE ALSO:
 *   <xp_strcpy> <xp_strncpy> <xp_strxcpy> <xp_strxncpy>
 */
xp_size_t xp_strcpyn (xp_char_t* buf, const xp_char_t* str, xp_size_t n);

/*
 * FUNCTION: xp_strncpy
 *   Copies a string with length into a buffer
 * 
 * PARAMETERS:
 *   buf - [out] the buffer into which a string is copied 
 *   str - [in] a string to copy
 *   len - [in] the length of *str*
 *
 * RETURNS:
 *   The number of characters copied excluding the terminating '\0', 
 *   which is equal to *len*.
 * 
 * DESCRIPTION:
 *   <xp_strncpy> copies any *len* characters from *str* and appends '\0' 
 *   to *buf* to guarantee to null-terminate it. The desirable size of *buf* 
 *   is *len* + 1 or greater.
 * 
 *   *str* may contain one or more '\0' characters as *len* denotes the 
 *   length of *str*. 
 * 
 * SEE ALSO:
 *   <xp_strcpy> <xp_strcpyn> <xp_strxcpy> <xp_strxncpy>
 */
xp_size_t xp_strncpy (xp_char_t* buf, const xp_char_t* str, xp_size_t len);

/*
 * FUNCTION: xp_strxcpy
 *   Copies a string into a size-bounded buffer
 *
 * PARAMETERS:
 *   buf - [out] the buffer into which a string is copied 
 *   bsz - [in] the size of *buf*
 *   str - [in] a null-terminated string to copy
 * 
 * RETURNS:
 *   The number of characters copied excluding the terminating '\0'.
 *
 * DESCRIPTION:
 *   <xp_strxcpy> copies all characters of *str* if *bsz* is greater than
 *   xp_strlen(*str*) and gurantees to null-terminate the resulting buffer.
 *   Otherwise, at most *bsz* - 1 characters of *str* are copied into *buf*
 *   and '\0' is inserted at *buf* [*bsz* - 1].
 *
 *   In many cases, it is safer to use <xp_strxcpy> than to use <xp_strcpy>
 *   because it does not write beyond the end of the buffer. Instead, if
 *   *str* is larger than *buf*, *buf* does not receive *str* in its entirety.
 * 
 * SEE ALSO:
 *   <xp_strcpy> <xp_strcpyn> <xp_strncpy> <xp_strxncpy>
 */
xp_size_t xp_strxcpy (xp_char_t* buf, xp_size_t bsz, const xp_char_t* str);

/*
 * FUNCTION: xp_strxncpy
 *   Copies a string with size into a size-bounded buffer
 * 
 * PARAMETERS:
 *   buf - [out] the buffer into which a string is copied 
 *   bsz - [in] the size of *buf*
 *   str - [in] a string to copy
 *   len - [in] the length of *str*
 *
 * RETURNS:
 *   The number of characters copied excluding the terminating '\0'.
 * 
 * DESCRIPTION:
 *   <xp_strxncpy> copies all characters of *str* if *bsz* is greater than
 *   *len* and gurantees to null-terminate the resulting buffer. Otherwise, 
 *   at most *bsz* - 1 characters of *str* are copied into *buf* and '\0' 
 *   is inserted at *buf* [*bsz* - 1].
 * 
 * SEE ALSO:
 *   <xp_strcpy> <xp_strcpyn> <xp_strncpy> <xp_strxcpy>
 */
xp_size_t xp_strxncpy (
	xp_char_t* buf, xp_size_t bsz, const xp_char_t* str, xp_size_t len);

/*---------------------
     string_concat.c 
  ---------------------*/

/* GROUP: Concatenation */

/* 
 * FUNCTION: xp_strcat
 *   Concatenates two nul-terminated strings
 * 
 * PARAMETERS:
 *   buf - [in out] a buffer containing a null-terminated string
 *   str - [in] a string to copy into *buf*
 * 
 * RETURNS:
 *   The number of characters in *buf* excluding the terminating '\0'
 *
 * DESCRIPTION:
 *    <xp_strcat> appends *str* into the existing string held in *buf*.
 *    The appended string is located from the position of the first null 
 *    character of *buf*. It stops concatenation if the terminating '\0' 
 *    of the string is copied. If *buf* is not large enough to receive 
 *    *str*, you may well expect memory-related bugs. 
 *    It returns xp_strlen(*buf*) + xp_strlen(*str*).
 * 
 * SEE ALSO:
 *   <xp_strcatn> <xp_strncat> <xp_strxcat> <xp_strxncat>
 */
xp_size_t xp_strcat (xp_char_t* buf, const xp_char_t* str);

/* 
 * FUNCTION: xp_strcatn
 *   Concatenates a length-bounded string with another string.
 * 
 * PARAMETERS:
 *   buf - [in out] a buffer containing a null-terminated string
 *   str - [in] a string to copy into *buf*
 *   n - [in] the maximum number of characters to copy if xp_strlen(*str*) > n
 *
 * RETURNS:
 *   The number of characters in *buf* excluding the terminating '\0'
 *
 * DESCRIPTION:
 *   <xp_strcatn> appends the first *n* characters of *str* into *buf*.
 *   If xp_strlen(*str*) is less than *n*, only the xp_strlen(*str*) + 1
 *   characters are appended. If xp_strlen(*str*) is equal to or greater
 *   than *n*, *buf* is not null-terminated. It expects a large *buf*
 *   enough to store *str*.
 *
 * SEE ALSO:
 *   <xp_strcat> <xp_strncat> <xp_strxcat> <xp_strxncat>
 */
xp_size_t xp_strcatn (xp_char_t* buf, const xp_char_t* str, xp_size_t n);

/* 
 * FUNCTION: xp_strncat
 *   Concatenates a null-terminated string and a length-bounded string
 * 
 * PARAMETERS:
 *   buf - [in out] a buffer containing a null-terminated string
 *   str - [in] a string to copy into *buf*
 *   len - [in] the number of characters to append from *str* 
 *
 * RETURNS:
 *   The number of resulting characters in *buf* excluding the terminating '\0'
 *
 * DESCRIPTION:
 *   <xp_strncat> appends *str* of the length *len* into *buf*. It guarantees
 *   to null-terminate *buf* with no side-effect when *buf* is large enough.
 *
 * SEE ALSO:
 *   <xp_strcat> <xp_strcatn> <xp_strxcat> <xp_strxncat>
 */
xp_size_t xp_strncat (xp_char_t* buf, const xp_char_t* str, xp_size_t len);

/* 
 * FUNCTION: xp_strxcat
 *   Concatenated two strings
 * 
 * PARAMETERS:
 *   buf - [in out] a buffer containing a null-terminated string
 *   bsz - [in] the maximum number of characters that *buf* can hold including the terminating '\0'
 *   str - [in] a null-terminated string to append
 *
 * RETURNS:
 *   The number of resulting characters in *buf* excluding the terminating '\0'
 * 
 * DESCRIPTION:
 *   <xp_strxcat> appends *str* into *buf*. It guarantees to null_terminate *buf*.
 *   However, the resulting string is truncated if *buf* is not large enough to 
 *   append all characters in *str*.
 *
 * SEE ALSO:
 *   <xp_strcat> <xp_strcatn> <xp_strncat> <xp_strxncat>
 */
xp_size_t xp_strxcat (xp_char_t* buf, xp_size_t bsz, const xp_char_t* str);

/* 
 * FUNCTION: xp_strxncat
 *   Concatenates a null-terminated string and a length-bounded string
 *
 * PARAMETERS:
 *   buf - [in out] a buffer containing a null-terminated string
 *   bsz - [in] the maximum number of characters that *buf* can hold including the terminating '\0'
 *   str - [in] a string to append
 *   len - [in] the length of *str*
 *
 * RETURNS:
 *   The number of resulting characters in *buf* excluding the terminating '\0'
 *
 * DESCRIPTION:
 *   <xp_strxncat> appends at most *len* characters of *str* into *buf*. 
 *   It guarantees to null-terminate *buf*. However, the resulting string is 
 *   truncated if *buf* is not large enough to append all *len* characters 
 *   of *str*.
 *
 * SEE ALSO:
 *   <xp_strcat> <xp_strcatn> <xp_strncat> <xp_strxcat>
 */
xp_size_t xp_strxncat (
	xp_char_t* buf, xp_size_t bsz, const xp_char_t* str, xp_size_t len);

/* 
 * FUNCTION: xp_strxapp
 *   Concatenates null-terminated strings into a buffer
 *
 * PARAMETERS:
 *   buf - [in out] the resulting buffer to hold the concatenated string
 *   size - [in] the size of *buf*
 *   ... - [in] null-terminated strings
 * 
 * RETURNS:
 *   The number of resulting characters in *buf* excluding the terminating '\0'
 *   
 * DESCRIPTION:
 *   <xp_strxapp> concatenates a varying number of null-terminated strings and
 *   put them into *buf*. The last string is indicated by XP_NULL. It stops 
 *   concatenation if *buf* is full to guarantee null-termination of *buf*.
 *
 * SEE ALSO:
 *   <xp_strxappv> <xp_strxcap> <xp_strxcapv>
 */
xp_size_t xp_strxapp (xp_char_t* buf, xp_size_t size, ...);

/* 
 * FUNCTION: xp_strxappv
 *   Concatenated null-terminated strings in the variable argument list
 *
 * PARAMETERS:
 *   buf - [in out] the resulting buffer to hold the concatenated string
 *   size - [in] the size of *buf*
 *   va - [in] variable argument list
 *
 * RETURNS:
 *   The number of resulting characters in *buf* excluding the terminating '\0'
 *
 * DESCRIPTION:
 *   <xp_strxappv> is similar to <xp_strxapp>, except that it accepts a single
 *   variable argument list.
 *
 * SEE ALSO:
 *   <xp_strxappv> <xp_strxcap> <xp_strxcap>
 */
xp_size_t xp_strxappv (xp_char_t* buf, xp_size_t size, xp_va_list ap);

/* 
 * FUNCTION: xp_strxcap
 *   Combines <xp_strxcat> and <xp_strxapp>
 */
xp_size_t xp_strxcap (xp_char_t* buf, xp_size_t size, ...);

/* 
 * FUNCTION: xp_strxcapv
 *   Combines <xp_strxcat> and <xp_strxappv>
 */
xp_size_t xp_strxcapv (xp_char_t* buf, xp_size_t size, xp_va_list ap);

/*---------------------
     string_compar.c 
  ---------------------*/

/* GROUP: Comparison */

/* 
 * FUNCTION: xp_strcmp
 */
int xp_strcmp (const xp_char_t* s1, const xp_char_t* s2);

/* 
 * FUNCTION: xp_strcmpn
 */
int xp_strcmpn (const xp_char_t* s1, const xp_char_t* s2, xp_size_t n);

/* 
 * FUNCTION: xp_strxcmp
 */
int xp_strxcmp (const xp_char_t* s1, xp_size_t len, const xp_char_t* s2);

/* 
 * FUNCTION: xp_strxncmp
 */
int xp_strxncmp (
	const xp_char_t* s1, xp_size_t len1, const xp_char_t* s2, xp_size_t len2);

/*
 * FUNCTION: xp_strcasecmp
 */
int xp_strcasecmp (const xp_char_t* s1, const xp_char_t* s2);

/*
 * FUNCTION: xp_strcasecmpn
 */
int xp_strcasecmpn (const xp_char_t* s1, const xp_char_t* s2, xp_size_t n);

/*
 * FUNCTION: xp_strncasecmp
 */
int xp_strncasecmp (const xp_char_t* s1, const xp_char_t* s2, xp_size_t count);

/*
 * FUNCTION: xp_strxcasecmp
 */
int xp_strxcasecmp (const xp_char_t* s1, xp_size_t len, const xp_char_t* s2);

/*
 * FUNCTION: xp_strxncasecmp
 */
int xp_strxncasecmp (
	const xp_char_t* s1, xp_size_t len1, const xp_char_t* s2, xp_size_t len2);

/*---------------------
     string_search.c 
  ---------------------*/

/* GROUP: Search */

/* 
 * FUNCTION: xp_strstr
 */
xp_char_t* xp_strstr (const xp_char_t* str, const xp_char_t* sub);

/* 
 * FUNCTION: xp_strxstr
 */
xp_char_t* xp_strxstr (
	const xp_char_t* str, xp_size_t size, const xp_char_t* sub);

/* 
 * FUNCTION: xp_strxnstr
 */
xp_char_t* xp_strxnstr (const xp_char_t* str,
	xp_size_t strsz, const xp_char_t* sub, xp_size_t subsz);

/* 
 * FUNCTION: xp_strrstr
 */
xp_char_t* xp_strrstr (const xp_char_t* str, const xp_char_t* sub);

/* 
 * FUNCTION: xp_strxrstr
 */
xp_char_t* xp_strxrstr (
	const xp_char_t* str, xp_size_t size, const xp_char_t* sub);

/* 
 * FUNCTION: xp_strxnrstr
 */
xp_char_t* xp_strxnrstr (const xp_char_t* str,
	xp_size_t strsz, const xp_char_t* sub, xp_size_t subsz);

/* 
 * FUNCTION: xp_strchr
 */
xp_char_t* xp_strchr (const xp_char_t* str, xp_cint_t c);

/* 
 * FUNCTION: xp_strxchr
 */
xp_char_t* xp_strxchr (const xp_char_t* str, xp_size_t len, xp_cint_t c);

/* 
 * FUNCTION: xp_strrchr
 */
xp_char_t* xp_strrchr (const xp_char_t* str, xp_cint_t c);

/* 
 * FUNCTION: xp_strxrchr
 */
xp_char_t* xp_strxrchr (const xp_char_t* str, xp_size_t len, xp_cint_t c);

/* 
 * FUNCTION: xp_strpbrk
 */
xp_char_t* xp_strpbrk (const xp_char_t* str, const xp_char_t* needle);

/* 
 * FUNCTION: xp_strxpbrk
 */
xp_char_t* xp_strxpbrk (
	const xp_char_t* str, xp_size_t n, const xp_char_t* needle);

/* 
 * FUNCTION: xp_strnpbrk
 */
xp_char_t* xp_strnpbrk (
	const xp_char_t* str, const xp_char_t* needle, xp_size_t n);

/* 
 * FUNCTION: xp_strxnpbrk
 */
xp_char_t* xp_strxnpbrk (
	const xp_char_t* str, xp_size_t n1, const xp_char_t* needle, xp_size_t n2);

/* 
 * FUNCTION: xp_strrpbrk
 */
xp_char_t* xp_strrpbrk (const xp_char_t* str, const xp_char_t* needle);

/* 
 * FUNCTION: xp_strxrpbrk
 */
xp_char_t* xp_strxrpbrk (
	const xp_char_t* str, xp_size_t n, const xp_char_t* needle);

/* 
 * FUNCTION: xp_strnrpbrk
 */
xp_char_t* xp_strnrpbrk (
	const xp_char_t* str, const xp_char_t* needle, xp_size_t n);

/* 
 * FUNCTION: xp_strxnrpbrk
 */
xp_char_t* xp_strxnrpbrk (
	const xp_char_t* str, xp_size_t n1, const xp_char_t* needle, xp_size_t n2);

/* 
 * FUNCTION: xp_strspn
 */
xp_size_t xp_strspn (
	const xp_char_t* str1, const xp_char_t* str2);

/* 
 * FUNCTION: xp_strxspn
 */
xp_size_t xp_strxspn (
	const xp_char_t* str1, xp_size_t n1, const xp_char_t* str2);

/* 
 * FUNCTION: xp_strnspn
 */
xp_size_t xp_strnspn (
	const xp_char_t* str1, const xp_char_t* str2, xp_size_t n2);

/* 
 * FUNCTION: xp_strxnspn
 */
xp_size_t xp_strxnspn (
	const xp_char_t* str1, xp_size_t n1, const xp_char_t* str2, xp_size_t n2);

/* 
 * FUNCTION: xp_strcspn
 */
xp_size_t xp_strcspn (
	const xp_char_t* str1, const xp_char_t* str2);

/* 
 * FUNCTION: xp_strxcspn
 */
xp_size_t xp_strxcspn (
	const xp_char_t* str1, xp_size_t n1, const xp_char_t* str2);

/* 
 * FUNCTION: xp_strncspn
 */
xp_size_t xp_strncspn (
	const xp_char_t* str1, const xp_char_t* str2, xp_size_t n2);

/* 
 * FUNCTION: xp_strxncspn
 */
xp_size_t xp_strxncspn (
	const xp_char_t* str1, xp_size_t n1, const xp_char_t* str2, xp_size_t n2);

/*---------------------
     string_rotate.c 
  ---------------------*/

/* GROUP: Rotation */

/* 
 * FUNCTION: xp_strrot
 */
xp_size_t xp_strrot (xp_char_t* str, int dir, xp_size_t n);

/* 
 * FUNCTION: xp_strxrot
 */
xp_size_t xp_strxrot (xp_char_t* str, xp_size_t len, int dir, xp_size_t n);

/* 
 * FUNCTION: xp_strrev
 */
xp_size_t xp_strrev (xp_char_t* str);

/* 
 * FUNCTION: xp_strxrev
 */
xp_size_t xp_strxrev (xp_char_t* str, xp_size_t len);

/* GROUP: Deletion */

/* 
 * FUNCTION: xp_strdel
 */
xp_size_t xp_strdel (xp_char_t* str, xp_size_t pos, xp_size_t n);

/* 
 * FUNCTION: xp_strxdel
 */
xp_size_t xp_strxdel (xp_char_t* str, xp_size_t len, xp_size_t pos, xp_size_t n);

/*
 * FUNCTION: xp_strrmchr
 * Removes all occurrences of a character from a null-terminated string
 *
 * PARAMETERS:
 * str - [in out] a string to examine
 * c - [in] a character to remove from the string
 *
 * RETURNS:
 * The length of the resulting string is returned.
 *
 * SEE ALSO:
 * <xp_strxrmchr>
 */
xp_size_t xp_strrmchr (xp_char_t* str, xp_cint_t c);

/*
 * FUNCTION: xp_strxrmchr
 * Removes all occurrences of a character from a string with length
 *
 * PARAMETERS:
 * str - [in out] a string to examine
 * len - [in] the length of the string
 * c - [in] a character to remove from the string
 *
 * RETURNS:
 * The length of the resulting string is returned. 
 *
 * SEE ALSO:
 * <xp_strrmchr>
 */
xp_size_t xp_strxrmchr (xp_char_t* str, xp_size_t len, xp_cint_t c);

/* string_ctype.c */
xp_bool_t xp_stristype (
	const xp_char_t* str, xp_bool_t(*ctype_func)(xp_cint_t c));
xp_bool_t xp_strxistype (
	const xp_char_t* str, xp_size_t len, xp_bool_t(*ctype_func)(xp_cint_t c));

xp_size_t xp_strupr (xp_char_t* str);
xp_size_t xp_strxupr (xp_char_t* str, xp_size_t len);
xp_size_t xp_strlwr (xp_char_t* str);
xp_size_t xp_strxlwr (xp_char_t* str, xp_size_t len);


xp_size_t xp_strtrm (xp_char_t* str);
xp_size_t xp_strxtrm (xp_char_t* str, xp_size_t len);
xp_size_t xp_strpac (xp_char_t* str);
xp_size_t xp_strxpac (xp_char_t* str, xp_size_t len);

xp_char_t* xp_strdup (const xp_char_t* str);
xp_char_t* xp_strxdup (const xp_char_t* str, xp_size_t len);

/* string_strtok.c */
xp_char_t* xp_strtok  (
	const xp_char_t*, const xp_char_t*, xp_char_t**, xp_size_t*);
xp_char_t* xp_strxtok (
	const xp_char_t*, xp_size_t, const xp_char_t*, xp_char_t**, xp_size_t*);

/* string_strspl.c */
int xp_strspl (xp_char_t* s, const xp_char_t* delim, 
	xp_char_t lquote, xp_char_t rquote, xp_char_t escape, xp_size_t* count);
int xp_strspls (
	xp_char_t* s, const xp_char_t* delim, xp_char_t lquote, xp_char_t rquote, 
	xp_char_t escape, xp_size_t* count, xp_char_t* ptrs[]);

/* string_strfnmat.c */
int xp_strfnmat (const xp_char_t* str, const xp_char_t* ptn, int flags);
xp_bool_t xp_strxfnmat  (
	const xp_char_t* str, xp_size_t slen, const xp_char_t* ptn, int flags);
xp_bool_t xp_strnfnmat  (
	const xp_char_t* str, const xp_char_t* ptn, xp_size_t plen, int flags);
int xp_strxnfnmat (
	const xp_char_t* str, xp_size_t slen, 
	const xp_char_t* ptn, xp_size_t plen, int flags);

/* string_strtodn.c */
xp_size_t xp_strtodn (
	const xp_char_t* name, xp_byte_t* buf, xp_size_t bufsz);
xp_size_t xp_strxtodn (
	const xp_char_t* name, xp_size_t nsz, xp_byte_t* buf, xp_size_t bufsz);
xp_size_t xp_strfromdn (
	const xp_byte_t* dn, xp_size_t dnsz, xp_char_t* buf, xp_size_t bufsz);
xp_size_t xp_strxfromdn (
	const xp_byte_t* dn, xp_size_t dnsz, xp_char_t* buf, xp_size_t bufsz);

/* GROUP: Vectorized String */

/*
 * FUNCTION: xp_vstr_open 
 */
xp_vstr_t* xp_vstr_open (xp_vstr_t* vec);

/*
 * FUNCTION: xp_vstr_close 
 */
void xp_vstr_close (xp_vstr_t* vec);

/*
 * FUNCTION: xp_vstr_clear 
 */
void xp_vstr_clear (xp_vstr_t* vec);

/*
 * FUNCTION: xp_vstr_append 
 */
int xp_vstr_append (xp_vstr_t* vec, const xp_char_t* str);

#ifdef __cplusplus
}
#endif

#endif

